package com.lawyer.util.base64;

import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Timestamp;
import java.text.NumberFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 加密工具类
 */
@SuppressWarnings("restriction")
public class BASE64EncoderUtil {

	/**
	 * BASE64加密
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String incodeBase64(byte[] key) throws Exception {
		return (new BASE64Encoder()).encodeBuffer(key);
	}

	/***
	 * 
	 * @param number
	 * @param index
	 * @return
	 */
	public static double numberFormat(double number, int index) {
		NumberFormat nf = NumberFormat.getInstance();
		nf.setMaximumFractionDigits(index);
		return Double.valueOf(nf.format(number).replace(",", ""));

	}

	public static String numberFormatPercence(double number, int index) {
		NumberFormat nf = NumberFormat.getPercentInstance();
		nf.setMaximumFractionDigits(index);
		return nf.format(number);

	}

	public static double round(double value, int index) {
		BigDecimal big = new BigDecimal(value);
		@SuppressWarnings("static-access")
		BigDecimal afterBig = big.setScale(index, big.ROUND_HALF_UP);
		return afterBig.doubleValue();
	}

	@SuppressWarnings("static-access")
	public static double roundHalfDown(double value, int index) {
		BigDecimal big = new BigDecimal(value);
		BigDecimal afterBig = big.setScale(index, big.ROUND_HALF_DOWN);
		return afterBig.doubleValue();
	}

	/**
	 * 将字节数"BASE64 编码
	 *
	 * @author hexiang
	 * @param b
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String encodeBase64(byte[] b)
			throws UnsupportedEncodingException {
		if (b == null)
			return null;
		Base64 base64 = new Base64();

		return new String(base64.encode(b), "UTF-8");

		/*
		 * BASE64Encoder encoder = new BASE64Encoder(); return
		 * encoder.encode(b);
		 */
	}

	/**
	 * 写响应内容给客户"
	 * 
	 * @param responseContent
	 *            "��返回给客户端的响应内"
	 * @throws IOException
	 */
	public static void writerResponse(HttpServletResponse httpServletResponse,
			String responseContent) throws IOException {
		PrintWriter pw = null;
		httpServletResponse.setContentType("text/xml;charset=utf-8");
		pw = httpServletResponse.getWriter();
		pw.print(responseContent);
		pw.close();
		pw = null;
	}

	/**
	 * 从客户端读取请求内容
	 * 
	 * @return 从客户端读取请求内容
	 * @throws IOException
	 */
	public static String readRequest(HttpServletRequest request)
			throws IOException {

		BufferedReader br = new BufferedReader(new InputStreamReader(
				request.getInputStream(), "UTF-8"));
		String line = null;
		StringBuilder sb = new StringBuilder();
		while ((line = br.readLine()) != null) {
			sb.append(line);
		}

		return sb.toString();
	}

	/**
	 * 从客户端读取请求内容不转"
	 * 
	 * @return 从客户端读取请求内容
	 * @throws IOException
	 */
	public static String readRequestByDefaultCharset(HttpServletRequest request)
			throws IOException {

		BufferedReader br = new BufferedReader(new InputStreamReader(
				request.getInputStream()));
		String line = null;
		StringBuilder sb = new StringBuilder();
		while ((line = br.readLine()) != null) {
			sb.append(line);
		}

		return sb.toString();
	}

	public static String byte2hex(byte b[]) {
		if (b == null || b.length == 0) {
			return null;
		}
		StringBuffer strbuf = new StringBuffer(b.length * 2);
		int i;

		for (i = 0; i < b.length; i++) {
			if (((int) b[i] & 0xFF) < 0x10)
				strbuf.append("0");

			strbuf.append(Long.toString((int) b[i] & 0xFF, 16));
		}
		return strbuf.toString().toUpperCase();
	}

	public static byte[] hex2byte(String s) {
		if (s == null || s.length() == 0) {
			return null;
		}

		byte[] arrB = s.toUpperCase().getBytes();
		int iLen = arrB.length;

		// 两个字符表示"��字节，所以字节数组长度是字符串长度除"
		byte[] arrOut = new byte[iLen / 2];
		for (int i = 0; i < iLen; i = i + 2) {
			String strTmp = new String(arrB, i, 2);
			arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
		}
		return arrOut;
	}

	/**
	 * JAVA标准SHA-1算法，直接base64编码后的字符"
	 *
	 * @throws IOException
	 */
	public static String getHashUsedSHA1(byte[] input)
			throws NoSuchAlgorithmException, UnsupportedEncodingException {
		MessageDigest md = MessageDigest.getInstance("SHA-1");
		return encodeBase64(md.digest(input));

	}

	/**
	 * JAVA标准MD5算法，直接base64编码后的字符"
	 * 
	 * @throws IOException
	 */
	public static byte[] getDigestByMD5(String src)
			throws NoSuchAlgorithmException, IOException {
		MessageDigest md = MessageDigest.getInstance("MD5");
		return md.digest(src.getBytes("UTF-8"));
	}

	/**
	 * 将shor类型转为byte数组
	 * 
	 * @author hexiang
	 * @param n
	 * @return
	 */
	public static byte[] short2byte(int n) {
		byte b[] = new byte[2];
		b[0] = (byte) (n >> 8);
		b[1] = (byte) n;
		return b;
	}

	/**
	 * 将int类型转为byte数组
	 * 
	 * @author hexiang
	 * @param n
	 * @return
	 */
	public static byte[] int2byte(int n) {
		byte b[] = new byte[4];
		b[0] = (byte) (n >> 24);
		b[1] = (byte) (n >> 16);
		b[2] = (byte) (n >> 8);
		b[3] = (byte) n;
		return b;
	}

	/**
	 * 将long类型转为byte数组
	 * 
	 * @author hexiang
	 * @param n
	 * @return
	 */
	public static byte[] long2byte(long n) {
		byte b[] = new byte[8];
		b[0] = (byte) (int) (n >> 56);
		b[1] = (byte) (int) (n >> 48);
		b[2] = (byte) (int) (n >> 40);
		b[3] = (byte) (int) (n >> 32);
		b[4] = (byte) (int) (n >> 24);
		b[5] = (byte) (int) (n >> 16);
		b[6] = (byte) (int) (n >> 8);
		b[7] = (byte) (int) n;
		return b;
	}

	public static short byte2short(byte b[]) {
		/*
		 * return ((short)(b[1] | b[0]<<8));
		 */

		return (short) (b[1] & 0xff | (b[0] & 0xff) << 8);
	}

	public static int byte2int(byte b[]) {
		return b[3] & 0xff | (b[2] & 0xff) << 8 | (b[1] & 0xff) << 16
				| (b[0] & 0xff) << 24;
	}

	public static long byte2long(byte b[]) {
		return ((long) (b[7] & 0xff)) | ((long) (b[6] & 0xff)) << 8
				| ((long) (b[5] & 0xff)) << 16 | ((long) (b[4] & 0xff)) << 24
				| ((long) (b[3] & 0xff)) << 32 | ((long) (b[2] & 0xff)) << 40
				| ((long) (b[1] & 0xff)) << 48 | ((long) (b[0] & 0xff)) << 56;
	}

	/*
	 * public static long byte2long(byte b[]) { return (long) b[7] & (long) 255
	 * | ((long) b[6] & (long) 255) << 8 | ((long) b[5] & (long) 255) << 16 |
	 * ((long) b[4] & (long) 255) << 24 | ((long) b[3] & (long) 255) << 32 |
	 * ((long) b[2] & (long) 255) << 40 | ((long) b[1] & (long) 255) << 48 |
	 * (long) b[0] << 56; }
	 */

	public static String printByte(byte[] b) {
		StringBuffer sb = new StringBuffer();
		if (b == null || b.length == 0)
			return "[]";
		sb.append("[");
		for (int i = 0; i < b.length; i++) {
			sb.append(b[i]).append(",");
		}
		sb.setCharAt(sb.length() - 1, ']');
		return sb.toString();
	}

	/**
	 * 生成编号：一位字"13位时"2位随机数
	 * 
	 * @param str
	 *            "��字符[用户编号用"U"借款申请单编号"B"投标编号用"L"待审核机构编号用“A"
	 *            交易号用"C",日志编号"G"] 借款申请过程记录"的单号用T"��
	 * @return
	 */
	// public static String getId(String str ){
	// char[] codeSerial = {
	// 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
	// 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
	// 'Y', 'Z' ,'0','1','2','3','4','5','6','7','8','9'};
	// String ranNumber = "";
	// // 生成"��2位数的随机码
	// for (int i = 0; i < 2; i++) {
	// // 取索引为0-35以内的随机数，从codeSeria中取
	// int a = (new Random()).nextInt(36);
	// ranNumber += codeSerial[a];
	// }
	//
	// return str+System.currentTimeMillis()+ranNumber;
	// }
	/**
	 * 生成编号：一位字"13位时"2位随机数
	 * 
	 * @param pre
	 *            "��字符[用户编号用"U"借款申请单编号"B"投标编号用"L"待审核机构编号用“A"
	 *            交易号用"C",日志编号"G"]
	 * @return
	 */
	public synchronized static String getId(String pre) {
		AtomicInteger useratomic = new AtomicInteger();
		long now = new Date().getTime();
		String inc = to2Bit(useratomic.incrementAndGet());
		useratomic.compareAndSet(99, 0);
		return pre + now + inc;
	}

	public static String to2Bit(int aa) {
		String ret = aa + "";
		while (ret.length() < 2) {
			ret = "0" + ret;
		}
		return ret;
	}

	/**
	 * 获取当前时间
	 * 
	 * @return
	 */
	public static Date getCurrentDateTime() {
		Date date = new Date();
		Timestamp timeStamp = new Timestamp(date.getTime());
		return timeStamp;
	}

	/**
	 * long型转换成日期"
	 * 
	 * @param l
	 * @return
	 */
	public static Date long2DateTime(long l) {
		Date date = new Date(l);
		return new Timestamp(date.getTime());
	}

	/**
	 * 日期型转换成long"
	 * 
	 * @param d
	 * @return
	 */
	public static long dateTime2Long(Date d) {
		long lSysTime1 = d.getTime() / 1000;
		return lSysTime1;
	}

	/**
	 * 获取6位验证码
	 * 
	 * @return
	 */
	public static String getVeryCode() {
		char[] codeSerial = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
				'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
				'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
				'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
				'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5',
				'6', '7', '8', '9' };
		String ranNumber = "";
		// 生成"��2位数的随机码
		for (int i = 0; i < 6; i++) {
			// 取索引为0-35以内的随机数，从codeSeria中取
			int a = (new Random()).nextInt(62);
			ranNumber += codeSerial[a];
		}

		return ranNumber;
	}

	
	public static boolean GenerateImage(String imgStr, String imgFilePath, String fileName, String userId) { // 对字节数组字符串进行Base64解码并生成图片
		if (imgStr == null) // 图像数据为空
			return false;

		File targetPath = new File(imgFilePath + userId);
		if (!targetPath.exists()) {
			targetPath.mkdirs();
		}

		File targetFile = new File(targetPath, fileName);
		if (!targetFile.exists()) {
			try {
				targetFile.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		BASE64Decoder decoder = new BASE64Decoder();
		try {
			FileOutputStream write = new FileOutputStream(new File(imgFilePath+ userId+File.separator+fileName));
			imgStr=imgStr.substring(23);
//			LoggerUtil.info(logger, "subject======, imgStr======", "GenerateImage", "图片格式转化");
			byte[] decoderBytes = decoder.decodeBuffer(imgStr);
			write.write(decoderBytes);
			write.close();
//			logger.info("imgFilePath +userId+File.separator+fileName"+imgFilePath +userId+File.separator+fileName);
			ImgCompress.ImgRar(imgFilePath +userId+File.separator+fileName);
			return true;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	
//		
	}
	
	/** 
     * 把base64图片数据转为本地图片 
     * @param base64ImgData 
     * @param filePath 
     * @throws IOException 
     */  
    public static void convertBase64DataToImage(String base64ImgData,String filePath) throws IOException {  
        BASE64Decoder d = new BASE64Decoder();  
        byte[] bs = d.decodeBuffer(base64ImgData);  
        FileOutputStream os = new FileOutputStream(filePath);  
        os.write(bs);  
        os.close();  
    } 
}
